package com.usefullc.user.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.usefullc.common.exception.BizException;
import com.usefullc.common.user.OnlineUser;
import com.usefullc.common.user.OnlineUserManager;
import com.usefullc.common.util.BeanUtils;
import com.usefullc.system.entity.Pager;
import com.usefullc.system.service.AbstractBizService;
import com.usefullc.system.service.SerialNumberService;
import com.usefullc.system.vo.TreeVo;
import com.usefullc.user.domain.Dept;
import com.usefullc.user.domain.Position;
import com.usefullc.user.mapper.DeptMapper;
import com.usefullc.user.query.DeptQuery;
import com.usefullc.user.query.PositionQuery;
import com.usefullc.user.vo.DeptVo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: Sampson
 * @date: 2022-01-09 09:58
 */
@Service
public class DeptService extends AbstractBizService<DeptMapper,Dept,DeptQuery> {


    @Autowired
    private SerialNumberService serialNumberService;

    @Override
    protected QueryWrapper<Dept> getQueryWrapper(DeptQuery query) {
        OnlineUser loginUser = OnlineUserManager.getLoginUser();
        if(loginUser != null && loginUser.getTenantId() != 0L){
            query.setTenantId(loginUser.getTenantId());
        }
        return super.getQueryWrapper(query);
    }


    public List<Dept> getChildrenByCodeLike(String codeLike) {
        DeptQuery query = new DeptQuery();
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        query.setCodeLike(codeLike);
        return this.findAll(query);
    }

    public List<Dept> getChildrenByParentId(Long parentId) {
        DeptQuery query = new DeptQuery();
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        query.setParentId(parentId);
        return this.findAll(query);
    }


    public Pager<DeptVo> listByPage(DeptQuery query) {
        query.setParentId(0L);
        query.setOrderByColumn("orderNo");
        query.setAscOrDesc("asc");
        Pager<Dept> pager = this.findByPage(query);
        List<Dept> dataList = pager.getDataList();
        Pager<DeptVo> newPager = new Pager<>(pager);
        List<DeptVo> newDataList = new ArrayList<>();
        newPager.setDataList(newDataList);
        if (CollectionUtils.isNotEmpty(dataList)) {
            for (Dept dept : dataList) {
//                deptVo.setChildren(Lists.newArrayList());
                DeptVo deptVo = BeanUtils.beanCopy(dept, DeptVo.class);
                newDataList.add(deptVo);

                //

                List<DeptVo> children = new ArrayList<>();
                //获取子集
                List<Dept> childDataList = getChildrenByCodeLike(dept.getCode());

                setChildren(childDataList,children,deptVo);

            }
        }
        return newPager;
    }

    private void setChildren(List<Dept> childDataList, List<DeptVo> children, DeptVo deptVo){
        for (Dept dept : childDataList) {
            if (dept.getParentId() != deptVo.getId().longValue()) {
                continue;
            }
            DeptVo childDeptVo = BeanUtils.beanCopy(dept, DeptVo.class);
            children.add(childDeptVo);
            List<DeptVo> subChildren = new ArrayList<>();
            setChildren(childDataList,subChildren,childDeptVo);
        }
        if(children.size() > 0){
            deptVo.setChildren(children);
        }
    }

    public List<TreeVo> listTree(DeptQuery query){
        query.setParentId(0L);
        List<Dept> dataList = this.findAll(query);
        List<TreeVo> newDataList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(dataList)) {
            for (Dept dept : dataList) {
                TreeVo treeVo = new TreeVo();
                newDataList.add(treeVo);
                treeVo.setTitle(dept.getName());
                treeVo.setValue(dept.getId().toString());
                treeVo.setKey(dept.getId().toString());
                List<TreeVo> children = new ArrayList<>();
                //获取子集
                List<Dept> childDataList = getChildrenByCodeLike(dept.getCode());

                setTreeChildren(childDataList,children,treeVo);
            }
        }
        return newDataList;
    }

    private void setTreeChildren(List<Dept> childDataList, List<TreeVo> children, TreeVo treeVo){
        for (Dept childDept : childDataList) {
            if (childDept.getParentId() != Long.valueOf(treeVo.getValue()).longValue()) {
                continue;
            }
            TreeVo childTreeVo = new TreeVo();
            childTreeVo.setTitle(childDept.getName());
            childTreeVo.setValue(childDept.getId().toString());
            childTreeVo.setKey(childDept.getId().toString());
            children.add(childTreeVo);

            List<TreeVo> subChildren = new ArrayList<>();
            setTreeChildren(childDataList,subChildren,childTreeVo);
        }
        if(children.size() > 0){
            treeVo.setChildren(children);
        }
    }


    public Dept findByUserId(Long userId){
        DeptQuery query = new DeptQuery();
        query.setUserId(userId);
        return this.findOne(query);
    }

    public Dept saveDept(Dept dept) {
        Long parentId = dept.getParentId();
        if (parentId == null) {
            parentId = 0L;
        }
        String parentCode = "0";
        if(parentId != 0){
            parentCode = this.findById(parentId).getCode();
        }
        dept.setParentId(parentId);
        String no = serialNumberService.getSerialNumber("sys_dept", parentCode);
        dept.setCode(no);
        this.save(dept);
        return dept;
    }

    public Dept updateDept(Dept dept){
        Long parentId = dept.getParentId();
        if (parentId == null) {
            parentId = 0L;
        }
        if(parentId.longValue() == dept.getId()){
            throw new BizException("不能作为自己的父级",false);
        }
        Dept oldBean = this.findById(dept.getId());
        Long oldParentId = oldBean.getParentId();
        BeanUtils.beanCopy(dept,oldBean);
        if(oldParentId == parentId.longValue()){  //直接修改属性
            this.update(oldBean);
        }else{  //修改了父级，则涉及到的编码包括该级的下一级编码都得改
            String parentCode = "0";
            if(parentId != 0){
                parentCode = this.findById(parentId).getCode();
            }
            String no = serialNumberService.getSerialNumber("sys_dept", parentCode);
            oldBean.setCode(no);
            this.update(oldBean);

            //查询下一级修改
            updateChildrenForNo(oldBean.getId(),no);
        }
        return oldBean;
    }

    private void updateChildrenForNo(Long parentId,String parentNo){
        List<Dept> childDeptList = this.getChildrenByParentId(parentId);
        if(CollectionUtils.isNotEmpty(childDeptList)){
            for (Dept childDept : childDeptList) {
                String childNo = serialNumberService.getSerialNumber("sys_dept", parentNo);
                childDept.setCode(childNo);
                this.save(childDept);

                updateChildrenForNo(childDept.getId(),childNo);

            }
        }
    }



}
